﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace libC.semantic
{

    /// <summary>
    /// C 基本类型
    /// </summary>
    public enum CBaseType
    {
        _void,      //void
        _char,      //1 字节,-128 到 127 
        _uchar,     //1 字节,unsigned char ,0 到 255
        _short,     //2 字节,-32,768 到 32,767
        _ushort,    //2 字节,unsigned short, 0 到 65,535
        _int,       //4 字节, -2,147,483,648 到 2,147,483,647
        _uint,      //1 字节,0 到 4,294,967,295
        _long,      //4 字节,-2,147,483,648 到 2,147,483,647
        _ulong,     //4 字节,unsigned long,0 到 4,294,967,295
    }

    /// <summary>
    /// 语义性系 类型
    /// </summary>
    public enum SemanticInfoType
    {
        //表达式
        EXPR,
        //字段
        Field,
        //函数
        FUNCTION,
        //枚举
        ENUM,
        //结构体
        STRUCT,
        //类型别名
        TYPE_ALIAS
    }

    /// <summary>
    /// 语义信息
    /// </summary>
    public interface ISemanticInfo
    {
        /// <summary>
        /// 获取 语义的类型
        /// </summary>
        /// <returns></returns>
        SemanticInfoType getType();
        /// <summary>
        /// 获取语义节点名
        /// </summary>
        /// <returns></returns>
        string name { get; }
    }

    /// <summary>
    /// 在域中
    /// </summary>
    public interface IScopeIn
    {
        /// <summary>
        /// 域列表
        /// </summary>
        List<string> scopeArr { get; }
    }

    /// <summary>
    /// 字段 语义信息
    /// </summary>
    public class fieldInfo : ISemanticInfo
    {
        public fieldInfo(string name)
        {
            _name = name;
        }
        public SemanticInfoType getType()
        {
            return SemanticInfoType.Field;
        }

        public string name => _name;
        /// <summary>
        /// 声明 类型
        /// </summary>
        public string decl_type;

        private string _name;
    }

    /// <summary>
    /// 函数信息
    /// </summary>
    public class functionInfo : ISemanticInfo
    {
        public functionInfo(string name)
        {
            _name = name;
        }
        public SemanticInfoType getType()
        {
            return SemanticInfoType.FUNCTION;
        }
        //异常信息
        public string exception;
        public string name => _name;
        //是否是函数指针
        public bool isPoint = false;
        //函数是个 返回void ，且无参的函数
        public bool isVoidFun = false;
        //函数定义头部 ID
        public string firstID;
        //返回值类型
        public string ret_type;
        //参数列表 [参类型1,参名1,参类型2,参名2...]
        public List<string> args = new List<string>();
        //参数默认值字典 , {参名 : [val字符串 , val类型]}
        public Dictionary<string, List<string>> argDefVals = new Dictionary<string, List<string>>();
        private string _name;

    }

    /// <summary>
    /// 枚举信息
    /// </summary>
    public class enumInfo : ISemanticInfo, IScopeIn
    {
        public enumInfo(string name)
        {
            _name = name;
        }
        public SemanticInfoType getType()
        {
            return SemanticInfoType.ENUM;
        }
        public string name => _name;
        public List<string> scopeArr => _scopeArr;
        //是 class
        public bool isClass;
        //枚举限定类型
        public string enumType;
        //枚举列表 ，定义
        public List<string> enums_decl = new List<string>();
        private string _name;
        private List<string> _scopeArr = new List<string>();
    }

    /// <summary>
    /// 结构体 信息
    /// </summary>
    public class structInfo : ISemanticInfo, IScopeIn
    {
        public structInfo(string name)
        {
            _name = name;
        }
        public SemanticInfoType getType()
        {
            return SemanticInfoType.STRUCT;
        }
        public List<string> scopeArr => _scopeArr;
        public string name => _name;
        //结构列表 [类型,字段名,类型1,字段名1...]
        public List<string> decls = new List<string>();
        private string _name;
        private List<string> _scopeArr = new List<string>();
    }

    public class typeAliasInfo : ISemanticInfo
    {
        public typeAliasInfo(string name)
        {
            _name = name;
        }
        public SemanticInfoType getType()
        {
            return SemanticInfoType.TYPE_ALIAS;
        }
        public string name => _name;
        //源类型定义字符串
        public string srcType;
        //是一个 指针
        public bool isPoint;
        //是一个 数组
        public bool isArr;
        private string _name;
    }

    /// <summary>
    /// 语义AST节点
    /// </summary>
    public class semanticASTNode
    {
        public string type;                            //种类        
        public string text;                            //原始字符串信息
        public List<semanticASTNode> children = new List<semanticASTNode>();
        public uint id => _id;                                //节点ID

        private uint _id;
        /// <summary>
        /// 构建语义AST节点
        /// </summary>
        /// <param name="id">节点的ID</param>
        public semanticASTNode(uint id)
        {
            _id = id;
        }
    }

    public class semanticAST
    {
        //函数参数列表
        private const string keyPList = "parameter_list";
        //类型ID 第二个有效关键字
        private readonly static Dictionary<string, bool> secTypeIDdic = new Dictionary<string, bool>() { ["signed"] = true, ["unsigned"] = true };
        /// <summary>
        /// extern C 定义表
        /// </summary>
        public Dictionary<string, bool> defExternCDic = new Dictionary<string, bool>();
        /// <summary>
        ///自定义 类型表
        /// </summary>
        public Dictionary<string, uint> customTypeDic = new Dictionary<string, uint>();
        private uint lastNodeID = 0;
        private semanticASTNode _node;
        private stNode _stNode;
        private Stack<semanticASTNode> nodeStack = new Stack<semanticASTNode>();
        private Stack<string> structNStack = new Stack<string>();   //零时 结构名存储栈
        private Dictionary<string, string> variableTypeDic = new Dictionary<string, string>();  //变量类型声明表

        private Dictionary<uint, semanticASTNode> semanticNodeDic = new Dictionary<uint, semanticASTNode>();//ID 节点 字典
        private Dictionary<uint, ISemanticInfo> semanticInfoDic = new Dictionary<uint, ISemanticInfo>();//ID 语义信息 字典
        /// <summary>
        /// 获取节点
        /// </summary>
        public semanticASTNode node => _node;

        public semanticAST(stNode _stNode)
        {
            this._stNode = _stNode;
        }

        /// <summary>
        /// 执行解析
        /// </summary>
        /// <param name="rootNode"></param>
        public void parse()
        {
            ////排除 有 :: 节点 , C++ 的特性
            //if (_stNode.text.IndexOf("::") != -1) {
            //    return;
            //}

            //清理历史
            calcNode(_stNode);
            _node = nodeStack.Pop();
        }

        /// <summary>
        /// 获取节点的 semantInof
        /// </summary>
        /// <param name="nodeID">节点ID</param>
        /// <returns></returns>
        public ISemanticInfo getSemantInfo(uint nodeID)
        {
            ISemanticInfo result;
            semanticInfoDic.TryGetValue(nodeID, out result);
            return result;
        }

        /// <summary>
        /// 获取语义节点
        /// </summary>
        /// <param name="nodeID">节点ID</param>
        /// <returns></returns>
        public semanticASTNode getNode(uint nodeID)
        {
            semanticASTNode result;
            semanticNodeDic.TryGetValue(nodeID, out result);
            return result;
        }

        /// <summary>
        /// 获取一个 全新节点
        /// </summary>
        /// <returns></returns>
        private semanticASTNode newNode()
        {
            semanticASTNode result = new semanticASTNode(++lastNodeID);
            semanticNodeDic[result.id] = result;
            return result;
        }
        //获取一个 新节点
        private semanticASTNode newNode(string text, string type)
        {
            var result = newNode();
            result.text = text;
            result.type = type;
            return result;
        }

        /// <summary>
        /// 遍历 终节点
        /// </summary>
        /// <param name="_node">开始节点</param>
        /// <param name="callFun">回调委托</param>
        /// <param name="isLeft">是从左往右？</param>
        private static void eachTerminal(stNode _node, Action<stNode> callFun, bool isLeft = true)
        {
            if (_node == null) return;
            if (_node.children == null || _node.children.Count < 1)
            {
                callFun.Invoke(_node);
                return;
            }
            if (isLeft)
            {
                for (int i = 0, len = _node.children.Count; i < len; i++)
                {
                    var c = _node.children[i];
                    eachTerminal(c, callFun, isLeft);
                }
            }
            else
            {
                for (int i = _node.children.Count - 1; i >= 0; i--)
                {
                    var c = _node.children[i];
                    eachTerminal(c, callFun, isLeft);
                }
            }
        }

        /// <summary>
        /// 获取 左 末端节点
        /// </summary>
        /// <param name="_node">节点</param>
        /// <param name="isLeft">是否是左边</param>
        /// <returns></returns>
        private static stNode getTerminal(stNode _node, bool isLeft = true)
        {
            if (_node == null) return null;
            if (_node.children == null || _node.children.Count < 1) return _node;
            stNode n = _node;
            while (n.children != null && n.children.Count > 0)
            {
                n = isLeft ? n.children[0] : n.children[n.children.Count - 1];
            }
            return n;
        }
        //搜索 节点
        private static stNode searchNode(stNode _node, string nodetype, bool isLeft = true)
        {
            if (_node == null) return null;
            if (_node.type == nodetype) return _node;
            if (_node.children == null || _node.children.Count < 1) return null;
            for (int i = 0, len = _node.children.Count; i < len; i++)
            {
                var realIdx = isLeft ? i : len - (i + 1);
                var c = _node.children[realIdx];
                var _n = searchNode(c, nodetype, isLeft);
                if (_n != null) return _n;
            }

            return null;
        }
        //搜索子节点 ，所有匹配指定type的
        private static void searchNodes(List<stNode> outNodes, stNode _node, string nodetype, bool isLeft = true)
        {
            if (_node == null) return;
            if (_node.type == nodetype)
            {
                outNodes.Add(_node);
            }
            if (_node.children == null || _node.children.Count < 1) return;
            for (int i = 0, len = _node.children.Count; i < len; i++)
            {
                var realIdx = isLeft ? i : len - (i + 1);
                var c = _node.children[realIdx];
                searchNodes(outNodes, c, nodetype, isLeft);
            }
        }
        //获取 id_list 的 类型 字符串
        private static string getTypeID(stNode id_list)
        {
            string result = "";
            var id_lists = new List<stNode>();
            searchNodes(id_lists, id_list, "id_list");
            //左 1，类型名
            result = getTerminal(id_lists[id_lists.Count - 1]).text;
            if (id_lists.Count > 1)
            {
                //左 2，signed、unsigned
                string _secondStr = getTerminal(id_lists[id_lists.Count - 2]).text;
                if (secTypeIDdic.ContainsKey(_secondStr))
                {
                    result = $"{_secondStr} {result}";
                }
            }
            return result;
        }
        //分析计算 枚举
        private semanticASTNode calcEnum(stNode node)
        {
            semanticASTNode enum_Node = newNode(node.text, node.type);
            //枚举体 定义内容
            int nameIdx = 1;
            //class 处理
            stNode _class = searchNode(node, "'class'");
            if (_class != null) nameIdx += 1;
            enumInfo eInfo = new enumInfo(node.children[nameIdx].text);
            //copy scope
            if (structNStack.Count > 0)
            {
                var scopes = structNStack.ToArray();
                foreach (var item in scopes)
                {
                    eInfo.scopeArr.Add(item);
                }
            }
            semanticInfoDic.Add(enum_Node.id, eInfo);
            eInfo.isClass = _class != null;
            //节点ID 存入 类型字典
            customTypeDic[eInfo.name] = enum_Node.id;
            int _num = 2 + nameIdx;
            //枚举限定类型
            var id_list = searchNode(node, "id_list");
            if (id_list != null)
            {
                eInfo.enumType = getTypeID(id_list);
                _num += 2;
            }
            eInfo.enumType = enum_Node.type;
            int eLen = node.children.Count - (_num + 1);
            //空枚举 没有定义
            if (eLen < 1) return enum_Node;
            for (int i = 0; i < eLen; i++)
            {
                int realIdx = i + _num;
                var e_decl = node.children[realIdx];

                if (e_decl.text == ",") continue;
                //eName
                string eName = getTerminal(e_decl).text;
                string eVal = null;
                if (e_decl.children.Count == 3)
                {
                    var e_expr = e_decl.children[2];
                    //存表达式的字符串
                    eVal = e_expr.text;
                }
                //有表达式定义
                eInfo.enums_decl.Add(eName);
                eInfo.enums_decl.Add(eVal);
            }

            return enum_Node;
        }
        //分析计算 类型别名
        private semanticASTNode calcTypeAlias(stNode node)
        {
            //分析别名
            semanticASTNode tAlias_Node = newNode(node.text, node.type);
            int idx = -1;
            string srcType = "";
            bool hasParentheses = false;
            bool hasPoint = false;
            bool hasArr = false;
            string lastWord = "";
            eachTerminal(node, (_n) =>
            {
                idx++;
                if (idx == 0 || _n.text == ";") return;   //第一个和 最后一个跳过
                if (_n.text == "(" || _n.text == ")")
                {
                    hasParentheses = true;
                    return;
                }
                if (_n.text == "*")
                {
                    hasPoint = true;
                    return;
                }
                if (_n.text == "[" || _n.text == "]")
                {
                    hasArr = true;
                    return;
                }
                lastWord = _n.text;
                if (!hasParentheses)
                {
                    string sp = string.IsNullOrEmpty(srcType) ? "" : " ";
                    srcType += $"{sp}{_n.text}";   //类型
                }
            });
            typeAliasInfo taInfo = new typeAliasInfo(lastWord);
            semanticInfoDic.Add(tAlias_Node.id, taInfo);
            taInfo.srcType = srcType.Substring(0, srcType.Length - lastWord.Length - 1);
            taInfo.isPoint = hasPoint;
            taInfo.isArr = hasArr;
            return tAlias_Node;
        }
        //分析计算 函数
        private semanticASTNode calcFun(stNode node)
        {
            var id_list = searchNode(node, "id_list");
            if (id_list.children.Count < 2)
            {
                //只有类型定义，抛弃
                //Console.WriteLine($"抛弃函数 :{node.children[1].text} , 头部没有 动态库词条");
                return null;
            }

            semanticASTNode fun_Node = newNode(node.text, node.type);
            //函数声明名
            var decl_name = searchNode(node, "decl_name", false);
            var d_n_s = searchNode(decl_name, "decl_name_sub");
            bool isPoint = getTerminal(decl_name).text == "*";
            //名字
            bool isPointFun = false;
            string funName = getTerminal(d_n_s).text;
            if (funName == "(")
            {
                var mid_d_n = d_n_s.children[0].children[1];
                funName = getTerminal(mid_d_n, false).text;
                if (mid_d_n.children[0].text == "*")
                {
                    isPointFun = true;
                }
            }
            functionInfo fInfo = new functionInfo(funName);
            fInfo.isPoint = isPointFun;
            semanticInfoDic.Add(fun_Node.id, fInfo);
            //id_list 部分
            fInfo.firstID = getTerminal(id_list).text;
            fInfo.ret_type = getTypeID(id_list.children[1]);
            if (isPoint) fInfo.ret_type += "*";

            //参数列表
            var p_list = searchNode(decl_name, "parameter_list", false);
            if (p_list == null || p_list.children.Count < 1)
            {
                if (fInfo.ret_type == "void")
                {
                    fInfo.isVoidFun = true;
                }
                return fun_Node;
            }
            var p_list_c = p_list.children;
            for (int i = 0, len = p_list_c.Count; i < len; i++)
            {
                var c = p_list_c[i];
                if (c.text == ",") continue;
                //参数类型
                string p_type = null;
                //参数名
                string p_name = null;
                List<string> defVal = null;
                if (c.text != "...")
                {
                    var cChilds = c.children;
                    //参数类型
                    var p_scope = searchNode(c.children[0], "cpp_scope_type");
                    if (p_scope == null)
                    {
                        p_type = getTerminal(c.children[0], false).text;
                    }
                    else
                    {
                        //域处理
                        foreach (var item in p_scope.children)
                        {
                            if (item.text == "::")
                            {
                                p_type += ".";
                                continue;
                            }
                            p_type += item.text;
                        }
                    }

                    var expOffset = 0;
                    if (searchNode(c, "'='") != null)
                    {
                        defVal = new List<string>();
                        //有表达式
                        var p_exp_n = c.children[c.children.Count - 1];
                        if (p_exp_n.children != null && p_exp_n.children[0] != null)
                        {
                            p_exp_n = p_exp_n.children[0];
                        }
                        defVal.Add(p_exp_n.text);
                        defVal.Add(p_exp_n.type);
                        expOffset = 2;
                    }

                    if (cChilds.Count > (2 + expOffset))
                    {
                        var p_name_n = cChilds[cChilds.Count - (1 + expOffset)];
                        p_name = getTerminal(p_name_n, false).text;
                        if (searchNode(c, "POINTER") != null)
                        {
                            p_type += "*";
                        }
                        p_type += "&";
                    }
                    else if (cChilds.Count == (2 + expOffset))
                    {
                        var _cc = cChilds[1];
                        string _str = getTerminal(_cc).text;
                        //带指针 类型
                        if (_str == "*")
                        {
                            p_type += "*";
                        }
                        //参数名
                        var _p_name = _cc.children[_cc.children.Count - 1];
                        //最右端 "]" 判断 数组
                        if (getTerminal(_p_name, false).text == "]")
                        {
                            int exprIdx = _p_name.children.Count - 2;
                            var f_arr_expr = _p_name.children[exprIdx];
                            p_type += $"[{f_arr_expr.text}]";
                        }
                        p_name = getTerminal(_p_name).text;
                    }
                    else if (cChilds.Count == 1)
                    {
                        //无名参数
                        p_name = $"p{i}";
                    }
                }
                else
                {
                    //可变长 参数
                    p_name = "...";
                }

                fInfo.args.Add(p_type);
                fInfo.args.Add(p_name);
                if (defVal != null) fInfo.argDefVals[p_name] = defVal;

            }
            return fun_Node;
        }

        //通过 语法树 计算获取含语义的抽象语法树
        private void calcNode(stNode node)
        {
            string _typeStr = node.type;
            switch (_typeStr)
            {
                case "prog":
                    semanticASTNode progNode = newNode(node.text, node.type);
                    nodeStack.Push(progNode);
                    for (int i = 0, len = node.children.Count; i < len; i++)
                    {
                        calcNode(node.children[i]);
                    }
                    break;
                case "root":
                    if (node == null || node.children == null || node.children[0] == null) break;
                    calcNode(node.children[0]);
                    break;
                case "DEFINE":
                    //检查  导出 C 动态库的标记
                    //先检查 字符串头是否包含 #define ，有则获取 定义名
                    if (string.IsNullOrEmpty(node.text) || node.text.Length < 7 || node.text.Substring(0, 7) != "#define")
                    {
                        break;
                    }
                    //检查 extern "C"
                    string pattern = "extern( )*\"C\"";
                    if (!Regex.IsMatch(node.text, pattern)) break;
                    //定义名
                    string defName = node.text.Split(' ')[1];
                    //定义名 加 到表
                    defExternCDic[defName] = true;
                    break;
                case "fun_decl":
                    var f_semNode = calcFun(node);
                    if (f_semNode != null)
                    {
                        nodeStack.Peek().children.Add(f_semNode);
                    }
                    break;
                case "decl":
                    //var pLNode = searchNode(node, keyPList);
                    ////筛选是否有 parameter_list 
                    //var isFun = searchNode(node, keyPList) != null;
                    var isFun = false;
                    if (!isFun && node.children != null && node.children.Count > 1)
                    {
                        //从右到左 第二个节点
                        var scaLast = node.children[node.children.Count - 2];
                        var d_d_n_s = searchNode(scaLast, "decl_name_sub");
                        //函数 由 [函数名] [(] [)] 组成
                        if (d_d_n_s != null && d_d_n_s.children != null && d_d_n_s.children.Count > 2)
                        {
                            var cs = d_d_n_s.children;
                            isFun = cs[1].text == "(" && cs[cs.Count - 1].text == ")";
                        }
                    }
                    if (!isFun)
                    {
                        //是否是一个类型别名
                        var isTypeAblias = node.text.IndexOf("typedef") != -1;
                        if (!isTypeAblias)
                        {
                            calcNode(node.children[0]);
                        }
                        else
                        {
                            //别名
                            var d_taNode = calcTypeAlias(node);
                            if (d_taNode != null) nodeStack.Peek().children.Add(d_taNode);
                        }
                        break;
                    }

                    //走 fun_dcel处理
                    var d_f_semNode = calcFun(node);
                    if (d_f_semNode != null)
                    {
                        nodeStack.Peek().children.Add(d_f_semNode);
                    }
                    break;
                case "id_list":
                    calcNode(node.children[0]);
                    break;
                case "c_type":
                    calcNode(node.children[0]);
                    break;
                case "c_enum":
                    var enum_n = calcEnum(node);
                    if (enum_n != null)
                    {
                        nodeStack.Peek().children.Add(enum_n);
                    }
                    break;
                case "cpp_enum":
                    var cpp_enum_n = calcEnum(node);
                    if (cpp_enum_n != null)
                    {
                        nodeStack.Peek().children.Add(cpp_enum_n);
                    }
                    break;
                case "struct_union":
                    semanticASTNode struct_Node = newNode(node.text, node.type);
                    nodeStack.Peek().children.Add(struct_Node);
                    nodeStack.Push(struct_Node);    //入栈
                    //结构体定义内容
                    structInfo sInfo = new structInfo(node.children[1].text);
                    //copy scope
                    if (structNStack.Count > 0)
                    {
                        var scopes = structNStack.ToArray();
                        foreach (var item in scopes)
                        {
                            sInfo.scopeArr.Add(item);
                        }
                    }
                    structNStack.Push(sInfo.name);
                    semanticInfoDic.Add(struct_Node.id, sInfo);
                    //节点ID 存入 类型字典
                    customTypeDic[sInfo.name] = struct_Node.id;
                    //内部嵌套结构
                    int sLen = node.children.Count - 4;
                    if (sLen < 1)
                    {
                        nodeStack.Pop();    //出栈
                        structNStack.Pop();
                        break;
                    }

                    for (int i = 0; i < sLen; i++)
                    {
                        int realIdx = i + 3;
                        var s_decl = node.children[realIdx];
                        var s_name = "";
                        var s_type = "";
                        var s_id = s_decl.children[0];
                        //内部定义 子类型
                        //var s_idType = s_id.children[s_id.children.Count - 1].children[0];
                        //var typeIsSubDecl = s_idType.children != null && s_idType.children.Count > 1;
                        //是否是 结构 、枚举
                        stNode s_subDecl = null;
                        stNode s_struct_union = null;
                        stNode s_cEnum = null;
                        stNode s_cppEnum = null;
                        if ((s_struct_union = searchNode(s_id, "struct_union")) != null)
                        {
                            s_subDecl = s_struct_union;
                        }
                        else if ((s_cEnum = searchNode(s_id, "c_enum")) != null)
                        {
                            s_subDecl = s_cEnum;
                        }
                        else if ((s_cppEnum = searchNode(s_id, "cpp_enum")) != null) {
                            s_subDecl = s_cppEnum;
                        }

                        //是否有 c_type 节点
                        if (s_subDecl != null)
                        {
                            //走 calcNode
                            calcNode(s_subDecl);
                            var s_subN = struct_Node.children[struct_Node.children.Count - 1];   //查看
                            var s_subNSem = semanticInfoDic[s_subN.id];
                            s_type = s_subNSem.name;
                        }

                        var s_declVal = s_decl.children[1];
                        if (s_decl.children.Count < 3) continue;    //没定义名
                        if (string.IsNullOrEmpty(s_type))
                        {
                            s_type = getTerminal(s_id, false).text;
                            if (s_id.children.Count == 2)
                            {
                                string _secondStr = getTerminal(s_id).text;
                                if (secTypeIDdic.ContainsKey(_secondStr))
                                {
                                    s_type = $"{_secondStr} {s_type}";
                                }
                            }
                        }
                        var s_isPoint = getTerminal(s_declVal).text == "*";
                        if (s_isPoint)
                        {
                            s_type += "*";
                        }

                        //最右端 "]" 判断 数组
                        if (getTerminal(s_declVal, false).text == "]")
                        {
                            var s_d_n_cs = s_declVal.children[0].children;
                            var s_d_n_s = s_d_n_cs[s_d_n_cs.Count - 1];
                            var s_d_n_s_cs = s_d_n_s.children;
                            var f_arr_expr = s_d_n_s_cs[s_d_n_s_cs.Count - 2];
                            s_type += $"[{f_arr_expr.text}]";
                            s_name = getTerminal(s_d_n_s).text;
                        }
                        else
                        {
                            s_name = getTerminal(s_declVal, false).text;
                        }

                        //普通 结构体定义
                        sInfo.decls.Add(s_type);
                        sInfo.decls.Add(s_name);
                    }

                    structNStack.Pop();
                    nodeStack.Pop();    //出栈
                    break;
                case "cpp_class_decl":
                    //class 不处理
                    break;
            }
        }

        public void printTree()
        {
            if (_node == null) return;
            Console.WriteLine("==dump semant AST Tree ==");

            List<string> _l = new List<string>();
            dumpTree(_node, _l);
            foreach (var item in _l)
            {
                Console.WriteLine($"{item}");
            }
        }

        private void dumpTree(semanticASTNode node, List<string> list, int deep = 0)
        {
            //string str = "";
            //if (deep > 0)
            //{
            //    str = str.PadLeft(deep * 5, ' ');
            //}

            //str = str + node.type;
            //var children = node.children;

            //if (children.Count < 1 || node.text.Length <= 1)
            //{
            //    str += $":{node.text}";
            //    var _valType = getSemantInfo(node.id).decl_type;
            //    if (!String.IsNullOrEmpty(_valType))
            //    {
            //        str += $"<{_valType}>";
            //    }
            //}

            //list.Add(str);
            //for (int i = 0, len = children.Count; i < len; i++)
            //{
            //    var c = children[i];
            //    dumpTree(c, list, deep + 1);
            //}
        }
    }
}
